#ifndef SCENE_H
#define SCENE_H

#include <map>
#include <Box2D/Box2D.h>
#include "Common/Common.h"
#include "GameCore/Core.h"

#include "Common/IEntity.h"
#include "Common/ReusableBodyDef.h"
#include "Common/ReusableRotorDef.h"
#include "Map/Obstacle.h"
#include "Creature/Detail.h"
#include "Creature/Junction.h"
#include "Creature/Creature.h"
#include "Player/IPlayer.h"

#include "Camera.h"

class Scene
{
public:
	Scene();
	Scene( Camera* camera );
	~Scene();

	void Update( float dt );
	void Render();

	bool IsActive();

	int CreateCreature();
	void DeleteCreature( int id );

	int CreateDetail( int creatureId, const cmn::Transform& pos, const cmn::Transform& vel, const ReusableBodyDef* reusableBodyDef, const TextureInfo* texInfo );
	Detail* GetDetail( int detailId );
	void DeleteDetail( int creatureId, int detailId );

	int CreateJunction( int creatureId, const cmn::Vec2& anchor, int detailAId, int detailBId, ReusableRotorDef* reusableRotorDef );
	Junction* GetJunction( int junctionId );
	void DeleteJunction( int creatureId, int junctionId );

	int CreateObstacle( const cmn::Transform& pos, const ReusableBodyDef* reusableBodyDef, const TextureInfo* texInfo );
	Obstacle* GetObstacle( int obstacleId );
	void DeleteObstacle( int obstacleId );

	void AddRule( int partId, const Rule& rule );
	void RemoveRule( int partId, const Rule& rule );

	void AddLink( int creatureId, int partAId, int partBId );
	void RemoveLink( int creatureId, int partAId, int partBId );

	IEntity* GetEntity( int entityId );
	Part* GetPart( int partId );

	int CreateHumanPlayer( int creatureId );
	int CreateBotPlayer( int creatureId );
	void DeletePlayer( int playerId );

	inline Camera* GetCamera() const { return m_camera; }
	inline void SetCamera( Camera* camera ) { m_camera = camera; }

private:
	std::map<int, Creature*> m_creatures;
	std::map<int, Detail*> m_details;
	std::map<int, Junction*> m_junctions;
	std::map<int, Obstacle*> m_obstacles;
	std::map<int, IEntity*> m_entities;
	std::map<int, IPlayer*> m_players;

	b2World* m_world;
	Camera* m_camera;

private:
	static int m_currentId;
};
#endif
